#ifndef J_COOPERATIVE_TABLE_H
#define J_COOPERATIVE_TABLE_H
#pragma warning (disable:4786)
//------------------------------------------------------------------------
//
//  Name:   JCooperativeTable.h
//
//  Desc:   Converts the 2D Nav Graph into a cooperative Table
//		for use by path finding algorithms.
//          
// ---------------------------------------------------------------------
#include <cassert>
#include <string>
#include "2D/Vector2D.h"
#include "misc/utils.h" 
#include "graph/NodeTypeEnumerations.h"
#include "Graph/GraphEdgeTypes.h"
#include "Graph/GraphNodeTypes.h"
#include <vector>
#include <queue>
#include <deque>
#include <list>
#include "graph/SparseGraph.h"
#include "triggers/Trigger.h"
#include "Raven_Bot.h"
#include "PrecisionTimer.h"
#include "CrudeTimer.h"


class jCooperativeTable
{
	public:
		 typedef NavGraphNode<Trigger<Raven_Bot>*>      GraphNode;
		 typedef SparseGraph<GraphNode, NavGraphEdge>      NavGraph;

	 static jCooperativeTable& Instance()
		{
//    if (!m_pInstance)
			static jCooperativeTable m_pInstance;

		    return m_pInstance;
		}

	 		// Other non-static member functions
		//private:
		  jCooperativeTable();
		  jCooperativeTable(const jCooperativeTable&){};                 // Prevent copy-construction
		  jCooperativeTable& operator=(const jCooperativeTable&){};      // Prevent assignment
		  ~jCooperativeTable();

	 //Access functions
	 NavGraph* getGraphAtTime(int time)
	 {
		 if(time >= 0 && time < m_TimeDistance)
		  return m_SlicedSparseGraph[time];
	 }

	 int getTimeDistance()
	 {
		 return m_TimeDistance;
	 }

	 void ReserveNode(int time, int node)
	 {
	 }

	 void ReserveEdge(int time, int edge)
	 {
	 }

	 void Init(float travelTime, NavGraph* graph);
	 void Clear()
	 {
		 if (!m_SlicedSparseGraph.empty())
		 {
			 m_SlicedSparseGraph.clear();
	     }

	 }
	 
	 void MaintainTimeSlice();

	 void Update();


	protected:


		PrecisionTimer* m_timer;
		PrecisionTimer* m_Tabletimer;
		CrudeTimer* pCTimer;

		int m_TimeDistance;
		
		//determined by the time it takes an agent to go from node to node.
		float m_UpdateInterval;


		//Map version - NOT WORKING WELL AT ALL - Thought about using a Vector but you can't easily delete the first element
		//which is something i NEED TO DO!
		//std::map<int,NavGraph*>  m_SlicedSparseGraph;
		//std::map<int,NavGraph*>::iterator it;

//		std::queue<NavGraph*> m_SlicedSparseGraph;
		std::deque <NavGraph*> m_SlicedSparseGraph;

		
};

#endif